package com.wangyonghao.harmonyocrs.slice;

import com.wangyonghao.harmonyocrs.MainAbility;
import com.wangyonghao.harmonyocrs.ResourceTable;
import com.wangyonghao.harmonyocrs.utils.OCRUtils;
import com.wangyonghao.harmonyocrs.utils.ToastUtils;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.Camera;
import ohos.media.camera.device.CameraConfig;
import ohos.media.camera.device.CameraStateCallback;
import ohos.media.camera.device.FrameConfig;
import ohos.media.image.ImageReceiver;
import ohos.media.image.common.ImageFormat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class CameraAbilitySlice extends AbilitySlice {
    private Image back;
    private Image shot;
    private Button chooseButton;
    private Button reshot;
    private DirectionalLayout camera_view;
    private DirectionalLayout camera_menu;
    private SurfaceProvider surfaceProvider;

    private Surface proviewSurface;
    private boolean isFontCamera = false;

    private EventHandler handler = new EventHandler(EventRunner.create());
    private Camera cameraDevice;
    private ImageReceiver imageReceiver;

    private String imgSavePath;
    private File saveFile;
    private CameraKit cameraKit;
    private String cameraId;

    int cameraRequestCode = 2;
    //    Image camera;
//
//    int imgRequestCode = 1;
//    private SurfaceProvider surfaceProvider;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_camera);
        //设置切面全屏显示
        getWindow().addFlags(WindowManager.LayoutConfig.MARK_FULL_SCREEN |
                WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS |
                WindowManager.LayoutConfig.MARK_TRANSLUCENT_NAVIGATION);
        initComponent();
        event();

        createConfigShowBtnFunc();
    }

    //相机的预览
    private void createConfigShowBtnFunc() {
        //初始化surface,作用是将界面上显示组件和surface绑定
        initSurface();
    }

    //初始化surface,作用是将界面上显示组件和surface绑定
    private void initSurface() {
        surfaceProvider = new SurfaceProvider(this);
        surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceOpsCallback());//创建Surface后的回调
        surfaceProvider.pinToZTop(true);//没有组件在视频上面就是true，有就是false,不然视频上的组件点不到会被遮挡住，
        camera_view.addComponent(surfaceProvider);
    }

    private void initComponent() {
        back = (Image) findComponentById(ResourceTable.Id_camera_back);
        camera_view = (DirectionalLayout) findComponentById(ResourceTable.Id_camera_view);
        camera_menu = (DirectionalLayout) findComponentById(ResourceTable.Id_camera_menu);
        chooseButton = (Button) findComponentById(ResourceTable.Id_camera_choose_button);
        reshot = (Button) findComponentById(ResourceTable.Id_camera_reshot_button);
        shot = (Image) findComponentById(ResourceTable.Id_camera_shot);
//        camera = (Image) findComponentById(ResourceTable.Id_main_camera);
    }

    //
    private void event() {
        Context that = this;
        back.setClickedListener(e -> {
            camera_menu.setVisibility(Component.INVISIBLE);
            terminateAbility();
//            Intent i = new Intent();
//            Operation operation = new Intent.OperationBuilder()
//                    .withDeviceId("")
//                    .withBundleName(getBundleName())
//                    .withAbilityName(MainAbility.class.getName())
//                    .withAction("")
//                    .build();
//
//            i.setOperation(operation);
//            startAbility(i);
//            present(new MainAbilitySlice(), i);
        });
        shot.setClickedListener(e -> {
            takePhoto();
        });
        chooseButton.setClickedListener(e -> {
            //识别图片内容
            if (saveFile == null) {
                ToastUtils.showDialog(that, "您还未拍取照片");
            }
            if (saveFile.length() < 10000) {
                ToastUtils.showDialog(that, "照片体积太小，不能小于5k");
            }
            if (saveFile.length() > 10000000) {
                ToastUtils.showDialog(that, "照片体积太大，不能大于10M");
            }
            try {
                String s = OCRUtils.doOCR(saveFile);
                if (s == null || "".equals(s)) {
                    ToastUtils.showDialog(this, "未识别到任何内容！");
                }
                resultToMainPage(s);
//                proviewSurface.
            } catch (Exception ex) {
                ToastUtils.showDialog(this, "图片识别失败！");
                ex.printStackTrace();
            }
        });
        reshot.setClickedListener(e -> {
            camera_menu.setVisibility(Component.INVISIBLE);
            createCamera();
        });


    }

    private void takePhoto() {
        //处理拍照事件
        camera_menu.setVisibility(Component.VISIBLE);
        if (cameraDevice == null || imageReceiver == null) {
            ToastUtils.showDialog(this, "获取相机失败！");
        }
        FrameConfig.Builder frameConfigBuilder = cameraDevice.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_PICTURE);
        frameConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
        frameConfigBuilder.setImageRotation(90);//设置拍摄图片的旋转角度
        FrameConfig pictureFrameConfig = frameConfigBuilder.build();
        //触发相机的单帧捕获
        cameraDevice.triggerSingleCapture(pictureFrameConfig);
        //展示照片
        this.releaseCameraFunc();
    }

    private void resultToMainPage(String s) {
        Intent i = new Intent();
        i.setParam("result", s);
//        i.se
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId("")
                .withBundleName(getBundleName())
                .withAbilityName(MainAbility.class.getName())
//                .withAction("mainAbilitySlice")
                .build();
        i.setOperation(operation);
//        setResult(i);
        startAbility(i,2);
        //销毁当前Ability
        terminateAbility();
//        Intent i = new Intent();
//        presentForResult(new MainAbilitySlice(),i,cameraRequestCode);
    }

    private class SurfaceOpsCallback implements SurfaceOps.Callback {

        @Override
        public void surfaceCreated(SurfaceOps surfaceOps) {
            proviewSurface = surfaceOps.getSurface();
            //创建相机
            createCamera();
        }

        @Override
        public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

        }

        @Override
        public void surfaceDestroyed(SurfaceOps surfaceOps) {

        }
    }

    private void createCamera() {
        //在创建相机的方法里面初始化图像接收器
        //9是ImageReceiver的缓冲池大小
        imageReceiver = ImageReceiver.create(1080, 1080, ImageFormat.JPEG, 9);
        imageReceiver.setImageArrivalListener(this::saveImage);//设置保存图片的回调方法

        cameraKit = CameraKit.getInstance(getContext());
        String[] cameraIds = cameraKit.getCameraIds();
        if (cameraIds.length < 1) {
            resultToMainPage("当前设备无可用相机！可能正被其他程序占用");
            return;
        }
//        cameraId = cameraIds[0];
        cameraId = isFontCamera ? cameraIds[1] : cameraIds[0];
        cameraKit.createCamera(cameraId, new CameraStateCallbackImpl(), handler);

    }

    private void saveImage(ImageReceiver receiver) {
        imgSavePath = getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/IMG" + System.currentTimeMillis() + ".jpg";
        saveFile = new File(imgSavePath);
        ohos.media.image.Image image = receiver.readNextImage();
        ohos.media.image.Image.Component component = image.getComponent(ImageFormat.ComponentType.JPEG);
        byte[] bytes = new byte[component.remaining()];
        component.read(bytes);
        try (FileOutputStream output = new FileOutputStream(saveFile)) {
            output.write(bytes);
            output.flush();
            System.out.println("保存成功");
        } catch (IOException e) {
            System.out.println("保存失败");
            e.printStackTrace();
        }
    }

    private class CameraStateCallbackImpl extends CameraStateCallback {
        @Override
        public void onCreated(Camera camera) {
            //相机创建完的回调
            cameraDevice = camera;
            //接下来把之前创建好的Surface和这里的camera绑定起来
            CameraConfig.Builder cameraConfigBuilder = cameraDevice.getCameraConfigBuilder();
            cameraConfigBuilder.addSurface(proviewSurface);
            //设置拍照的Surface
            if (imageReceiver != null) {
                cameraConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
            }

            CameraConfig cameraConfig = cameraConfigBuilder.build();
            //最后设置相机设备
            cameraDevice.configure(cameraConfig);//这个函数执行成功后，会自动调用下边的onConfigured函数
        }

        @Override
        public void onConfigured(Camera camera) {
            //相机创建完的回调
            //相机配置完成后，就可以开始获取相机捕获的帧数据
            //帧配置构造器
            FrameConfig.Builder frameConfigBuilder = cameraDevice.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_PREVIEW);//设置相机的用途是用来预览
            frameConfigBuilder.addSurface(proviewSurface);//捕获到的帧传给了上面创建的surface工具，进而画到屏幕上的布局组件
            //开始捕获
            cameraDevice.triggerLoopingCapture(frameConfigBuilder.build());
        }
    }

    private void releaseCameraFunc() {
        if (cameraDevice != null) {
            //关闭相机和释放资源
            cameraDevice.release();
            cameraDevice = null;
        }
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        releaseCameraFunc();
    }

    @Override
    protected void onForeground(Intent intent) {
        super.onForeground(intent);
        if (cameraKit == null) {
            createCamera();
        } else {
            cameraKit.createCamera(cameraId, new CameraStateCallbackImpl(), handler);
        }
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {

    }
}
